import T from 'ant-design-vue/es/table/Table'
import Utils from './Utils'

export default {
  name: 'YsTable',
  data () {
    const defaultRowKey = 'id'
    return {
      inited: false,
      form: this.$form.createForm(this),
      tableResponse: null,
      defaultConfig: {
        showSearch: true,
        showToolbar: true,
        bordered: true,
        tableTitle: '',
        rowKey: defaultRowKey, // 主键
        showPagination: 'auto', // 分页
        size: 'default', // 表格大小
        filters: {},
        initialFilters: {},
        ops: {},
        pagination: {
          pageSize: 10, // 默认10条数
          current: 1,
          showSizeChanger: true,
          showTotal: (total, range) => this.__('table.pagination.showTotal', {
            range0: range[0],
            range1: range[1],
            total: total
          }),
          pageSizeOptions: ['10', '20', '50']
        },
        sorter: {
          field: defaultRowKey, // 默认ID降序
          order: 'descend'
        },
        searchExpand: false, // 是否展开搜索框
        queryParam: {}, // 查询参数
        url: null,
        data: null,
        dataSource: [],
        columns: [],
        showRowSelection: true,
        rowSelection: {
          selectedRowKeys: [],
          selectedRows: []
        },
        loading: false,
        extend: {
          actions: {}
        },
        toolbars: []
      },
      toolbar: {
        columnSetting: {
          checkAll: true,
          indeterminate: false,
          visibleColumns: {}
        }
      },
      tableColumnByDataIndex: {}
    }
  },
  props: {
    config: {
      type: Object,
      default: null
    }
  },
  watch: {
    'defaultConfig.pagination.current' (val) {
      // change pagination, reset total data
      this.defaultConfig.rowSelection && (this.defaultConfig.rowSelection.selectedRowKeys = [])
      this.defaultConfig.rowSelection && (this.defaultConfig.rowSelection.selectedRows = [])
    }
  },
  created () {
    this.defaultConfig = Object.assign({}, this.defaultConfig, this.config)
    const searchTable = this
    this.defaultConfig.columns.map((column, index) => {
      if (column.searchList instanceof Function) {
        const result = column.searchList(column, searchTable)
        if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
          result.then((res) => {
            column.searchList = res
          })
        }
      }
      column.formatter instanceof Function && (column.customRender = (val, row, index, column) => {
        const formatter = column.formatter
        // call 没有起作用
        return formatter(val, row, index, column, searchTable)
      })

      if (column.visible !== false) {
        this.toolbar.columnSetting.visibleColumns[index] = column
      }
      this.tableColumnByDataIndex[column.dataIndex] = column
    })
    const visibleColumnsLength = Object.keys(this.toolbar.columnSetting.visibleColumns).length
    this.toolbar.columnSetting.checkAll = visibleColumnsLength === this.defaultConfig.columns.length
    this.toolbar.columnSetting.indeterminate = !!visibleColumnsLength && visibleColumnsLength < this.defaultConfig.columns.length
    // 复选框
    if (this.defaultConfig.showRowSelection === true && this.defaultConfig.rowSelection) {
      this.defaultConfig.rowSelection = {
        ...this.defaultConfig.rowSelection,
        onChange: (selectedRowKeys, selectedRows) => {
          this.defaultConfig.rowSelection.selectedRowKeys = selectedRowKeys
          this.defaultConfig.rowSelection.selectedRows = selectedRows
        }
      }
    } else if (typeof this.defaultConfig.showRowSelection === 'function' && this.defaultConfig.rowSelection) {
      const config = this.defaultConfig
      this.defaultConfig.rowSelection = {
        ...this.defaultConfig.rowSelection,
        onChange: (selectedRowKeys, selectedRows) => {
          this.defaultConfig.rowSelection.selectedRowKeys = selectedRowKeys
          this.defaultConfig.rowSelection.selectedRows = selectedRows
        },
        getCheckboxProps (row) {
          return {
            props: { disabled: config.showRowSelection(row) }
          }
        }
      }
    }
  },
  mounted () {
    this.$on('refresh', (bool) => {
      this.refresh(bool)
    })
    // 加载数据
    this.$emit('refresh')
  },
  methods: {
    getSelectedRowsValueByKey (key) {
      const values = []
      const {
        rowSelection
      } = this.defaultConfig
      rowSelection.selectedRows.forEach((item) => {
        values.push(item[key])
      })
      return values
    },
    getTableColumnByDataIndex (dataIndex) {
      return this.tableColumnByDataIndex[dataIndex]
    },
    /**
     * 表格重新加载方法
     */
    refresh (bool = false) {
      bool && this.defaultConfig.showPagination && (this.defaultConfig.pagination.current = 1)
      bool && this.defaultConfig.rowSelection && (this.defaultConfig.rowSelection.selectedRowKeys = [])
      bool && this.defaultConfig.rowSelection && (this.defaultConfig.rowSelection.selectedRows = [])
      const {
        filters,
        ops
      } = this.form.getFieldsValue()
      if (filters) {
        Object.keys(filters).forEach((key) => {
          this.defaultConfig.ops[key] = undefined
          this.defaultConfig.filters[key] = undefined
          switch (ops[key]) {
            case 'RANGE':
              if (filters[key] instanceof Array) {
                filters[key][0].format instanceof Function && (filters[key][0] = filters[key][0].format('YYYY-MM-DD HH:mm:ss'))
                filters[key][1].format instanceof Function && (filters[key][1] = filters[key][1].format('YYYY-MM-DD HH:mm:ss'))
                this.defaultConfig.filters[key] = filters[key].join(',')
                if (this.defaultConfig.filters[key] === ',') {
                  this.defaultConfig.filters[key] = ''
                }
              }
              ops[key] = 'BETWEEN' // 将RANGE转成BETWEEN传给接口
              break
            case 'BETWEEN':
              if (filters[key] instanceof Array) {
                this.defaultConfig.filters[key] = filters[key].join(',')
                if (this.defaultConfig.filters[key] === ',') {
                  this.defaultConfig.filters[key] = ''
                }
              }
              break
            case 'LIKE':
              filters[key] && (filters[key] = '%' + filters[key] + '%')
              this.defaultConfig.filters[key] = filters[key]
              break
            default:
              this.defaultConfig.filters[key] = filters[key] instanceof Array ? filters[key].join(',') : filters[key]
          }
          this.defaultConfig.filters[key] === '' && (this.defaultConfig.filters[key] = undefined)
          this.defaultConfig.filters[key] && (this.defaultConfig.ops[key] = ops[key])

          const column = this.getTableColumnByDataIndex(key)
          if (column && column.searchName) {
            this.defaultConfig.filters[column.searchName] = this.defaultConfig.filters[key]
            this.defaultConfig.ops[column.searchName] = this.defaultConfig.ops[key]
            delete this.defaultConfig.filters[key]
            delete this.defaultConfig.ops[key]
          }
        })
      }
      this.loadData()
    },
    /**
     * 加载数据方法
     */
    loadData (pagination, filters, sorter) {
      this.defaultConfig.loading = true
      // 请求参数
      const parameter = {}
      // 处理分页参数
      pagination && (this.defaultConfig.pagination = Object.assign({}, this.defaultConfig.pagination, pagination))
      if (this.defaultConfig.showPagination) {
        parameter.offset = (this.defaultConfig.pagination.current - 1) * this.defaultConfig.pagination.pageSize
        parameter.limit = this.defaultConfig.pagination.pageSize
      } else {
        parameter.limit = 0
      }
      // 处理排序参数
      sorter && sorter.order || (sorter = this.defaultConfig.sorter)
      if (sorter) {
        let field = ''
        const column = this.getTableColumnByDataIndex(sorter.field)
        if (column && column.searchName) {
          field = column.searchName
        } else {
          field = sorter.field
        }
        parameter.sort = []
        switch (sorter.order) {
          case 'descend':
            parameter.sort.push(field + '-DESC')
            break
          case 'ascend':
            parameter.sort.push(field + '-ASC')
            break
          default:
            parameter.sort = null
        }
      }
      // 兼容filters参数
      if (filters) {
        Object.keys(filters).forEach((key) => {
          this.defaultConfig.filters[key] = filters[key] instanceof Array ? filters[key].join(',') : filters[key]
          this.defaultConfig.ops[key] = 'IN'
        })
      }
      // 处理查询参数
      if (this.defaultConfig.filters) {
        parameter.filters = this.defaultConfig.filters
        parameter.ops = this.defaultConfig.ops
      }
      var result = {}
      if (this.defaultConfig.url instanceof Function) {
        result = this.defaultConfig.url(parameter)
      } else {
        result = this.defaultConfig.data(parameter)
      }
      if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
        result.then(response => {
          this.tableResponse = response
          this.defaultConfig.pagination = this.defaultConfig.showPagination && Object.assign({}, this.defaultConfig.pagination, {
            total: response.data.data.total // 返回结果中的总记录数
          }) || false
          this.defaultConfig.dataSource = response.data.data.rows // 返回结果中的数组数据
          this.defaultConfig.loading = false
          this.inited = true
        }).catch(response => {
          this.tableResponse = response
          this.defaultConfig.dataSource = []
          this.defaultConfig.loading = false
          this.inited = true
          console.warn('table server api error ', response)
        })
      }
    },
    // 渲染表格搜索工具
    renderTableSearch () {
      var allColumns = this.defaultConfig.columns.filter((column) => {
        return column.ops !== false && column.dataIndex
      })
      if (allColumns.length === 0) {
        return ''
      }
      var columns = allColumns
      if (!this.defaultConfig.searchExpand) {
        columns = columns.slice(0, 2)
      }
      return (
        <a-form form={this.form} ref="form" labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
          <a-row gutter={48}>
            { columns.map(column => {
                const searchName = column.dataIndex
                var initialValue = this.defaultConfig.initialFilters[searchName]
                if (column.searchList) {
                  initialValue = initialValue ? initialValue.split(',') : undefined
                  return (
                    <a-col md={8} sm={24}>
                      <a-form-item label={column.title} style="margin-bottom:0;" help={column.help || ''}>
                        <a-input hidden v-decorator={['ops[' + searchName + ']', { initialValue: 'IN' }]}/>
                        <a-select
                          mode="multiple"
                          placeholder={column.placeholder || this.__('table.please.choose')}
                          optionFilterProp="children"
                          v-decorator={['filters[' + searchName + ']', { initialValue: initialValue }]}
                        >
                          {
                            Object.keys(column.searchList).map(key => {
                              return (
                                <a-select-option key={column.searchList[key]} value={key}>
                                  {column.searchList[key]}
                                </a-select-option>
                              )
                            })
                          }
                        </a-select>
                      </a-form-item>
                    </a-col>
                  )
                }
                column.ops && (column.ops = column.ops.toUpperCase())
                switch (column.ops) {
                  case 'RANGE':
                    initialValue = initialValue ? initialValue.split(',') : undefined
                    return (
                      <a-col md={8} sm={24}>
                        <a-form-item label={column.title} style="margin-bottom:0;" help={column.help || ''}>
                          <a-input hidden v-decorator={['ops[' + searchName + ']', { initialValue: 'RANGE' }]} />
                          <a-range-picker
                            v-decorator={['filters[' + searchName + ']', { initialValue: initialValue }]}
                            style="width: auto;"
                            show-time={{ format: 'HH:mm:ss' }}
                            format="YYYY-MM-DD HH:mm:ss"
                            placeholder={column.placeholder}
                            inputReadOnly={true} />
                        </a-form-item>
                      </a-col>
                    )
                  case 'BETWEEN':
                    initialValue = initialValue ? initialValue.split(',') : []

                    return (
                      <a-col md={8} sm={24}>
                        <a-form-item label={column.title} style="margin-bottom:0;" help={column.help || ''}>
                          <a-input hidden v-decorator={['ops[' + searchName + ']', { initialValue: 'BETWEEN' }]} />
                          <a-input-group compact style="border: 1px solid #d9d9d9; border-radius: 2px;">
                            <span style="width: 40%; ">
                              <a-input autoComplete="off" style="text-align: center; border: 0;" placeholder={column.placeholder || column.title} v-decorator={['filters[' + searchName + '][0]', { initialValue: initialValue[0] }]} />
                            </span>
                            <span style="width: 20%; ">
                              <a-input
                                style="min-width:10px; border: 0; pointer-events: none; backgroundColor: #fff"
                                value="~"
                                readOnly
                              />
                            </span>
                            <span style="width: 40%; ">
                              <a-input autoComplete="off" style="text-align: center; border: 0" placeholder={column.placeholder || column.title} v-decorator={['filters[' + searchName + '][1]', { initialValue: initialValue[1] }]} />
                            </span>
                          </a-input-group>
                        </a-form-item>
                      </a-col>
                    )
                  default:
                    return (
                      <a-col md={8} sm={24} style="margin-bottom:0;">
                        <a-form-item label={column.title} style="margin-bottom:0;" help={column.help || ''}>
                          <a-input hidden v-decorator={['ops[' + searchName + ']', { initialValue: column.ops || '=' }]} />
                          <a-input autoComplete="off" placeholder={(column.placeholder || column.title) + (column.ops === 'LIKE' ? '(模糊查询)' : '')} v-decorator={['filters[' + searchName + ']', { initialValue: initialValue }]}/>
                        </a-form-item>
                      </a-col>
                    )
                }
              }
            ) }
            <a-col md={8} sm={24}>
              <a-form-item style="margin-bottom:0;">
                <a-button-group>
                  <a-button type="primary" onClick={(e) => { Utils.events.refresh(e, this, true) }} loading={this.defaultConfig.loading}> {this.__('table.query')} </a-button>
                  <a-button onClick={(e) => {
                    this.form.resetFields()
                    Utils.events.refresh(e, this, true)
                  }}>{this.__('table.reset')}</a-button>
                  {
                    ((allColumns) => {
                      if (allColumns.length > 2) {
                        return (<a-button type="link" onClick={ () => { this.defaultConfig.searchExpand = !this.defaultConfig.searchExpand } }>
                          {this.defaultConfig.searchExpand ? this.__('table.searchExpand.up') : this.__('table.searchExpand.down')}
                          <a-icon type={this.defaultConfig.searchExpand ? 'up' : 'down'}/>
                        </a-button>)
                      }
                    })(allColumns)
                  }
                </a-button-group>
              </a-form-item>
            </a-col>
          </a-row>
        </a-form>
      )
    },
    // 渲染表格操作工具
    renderTableToolbar () {
      const tableToolbarButtons = []

      this.defaultConfig.extend.actions.add && tableToolbarButtons.push({
        name: 'add',
        url: '',
        icon: 'plus',
        title: this.__('table.add'),
        text: this.__('table.add'),
        on: {
          click: (e) => { Utils.events.add(e, this) }
        }
      })

      this.defaultConfig.extend.actions.delete && tableToolbarButtons.push({
        name: 'delete',
        url: '',
        icon: 'delete',
        title: this.__('table.delete'),
        text: this.__('table.delete'),
        type: 'danger',
        disabled: !this.defaultConfig.rowSelection || this.defaultConfig.rowSelection.selectedRowKeys.length <= 0,
        on: {
          click: (e) => {
            const p = {}
            p[this.defaultConfig.rowKey] = this.getSelectedRowsValueByKey(this.defaultConfig.rowKey).join(',')
            Utils.events.delete(e, this, p)
          }
        }
      })

      this.defaultConfig.toolbars.map((toolbar) => {
        toolbar.disabled = !this.defaultConfig.rowSelection || this.defaultConfig.rowSelection.selectedRowKeys.length <= 0
        if (toolbar.events) {
          toolbar.on || (toolbar.on = {})
          Object.keys(toolbar.events).forEach((eventType) => {
            toolbar.on[eventType] = (e) => {
              return toolbar.events[eventType](e, this)
            }
          })
        }
        tableToolbarButtons.push(toolbar)
      })

      return (
      <a-row type="flex" justify="space-around" align="middle" style="padding: 6px 0 10px 0">
        <a-col flex={2}>{
          (() => {
            if (this.defaultConfig.tableTitle) {
              return (<h2 style="margin:0;">{this.defaultConfig.tableTitle}</h2>)
            }
          })()
        }</a-col>
        <a-col flex={3}>
          <a-row type="flex" justify="end">
            <a-button-group style="margin-right: 8px">
              {
                tableToolbarButtons.map((button) => {
                  if (typeof button.formatter === 'function') {
                    return button.formatter.call(this, this)
                  } else {
                    const on = button.on || {}
                    const props = button
                    return (<a-button {...{ props, on }}> {button.text || button.title} </a-button>)
                  }
                })
              }
            </a-button-group>
            <a-button-group>
              <a-tooltip placement="top">
                <template slot="title"><span>{this.__('table.refresh')}</span></template><a-button icon="sync" style="border:none" onClick={(e) => { Utils.events.refresh(e, this) }} loading={this.defaultConfig.loading}></a-button>
              </a-tooltip>
              <a-tooltip placement="top">
                <template slot="title"><span>{this.__('table.fullscreen')}</span></template><a-button icon="fullscreen" style="border:none" onClick={ (e) => { Utils.events.fullscreen(e, this, this.$refs['table-wrapper']) } }></a-button>
              </a-tooltip>
              <a-tooltip placement="top">
                <template slot="title"><span>{this.__('table.columnHeight')}</span></template>
                <a-dropdown trigger={['click']}>
                  <a-menu slot="overlay">
                    <a-menu-item onClick={(e) => { Utils.events.columnHeight(e, this, 'default') }}>{this.__('table.columnHeight.default')}</a-menu-item>
                    <a-menu-item onClick={(e) => { Utils.events.columnHeight(e, this, 'middle') }}>{this.__('table.columnHeight.middle')}</a-menu-item>
                    <a-menu-item onClick={(e) => { Utils.events.columnHeight(e, this, 'small') }}>{this.__('table.columnHeight.small')}</a-menu-item>
                  </a-menu>
                  <a-button icon="column-height" style="border:none"></a-button>
                </a-dropdown>
              </a-tooltip>
              <a-tooltip placement="top">
                <template slot="title"><span>{this.__('table.columnSetting')}</span></template>
                <a-dropdown trigger={['click']}>
                  <a-menu slot="overlay" style="pointer-events: none;">
                      <a-menu-item style="padding: 0;">
                        <div style="border-bottom:1px solid #E9E9E9; padding: 5px 12px;" onClick={(e) => {
                          e.stopPropagation()
                          e.preventDefault()
                          this.toolbar.columnSetting.checkAll = this.toolbar.columnSetting.checkAll === false
                          this.toolbar.columnSetting.indeterminate = false
                          this.toolbar.columnSetting.visibleColumns = {}
                          this.defaultConfig.columns.map((item, index) => {
                            item.visible = this.toolbar.columnSetting.checkAll
                            if (item.visible !== false) {
                              this.toolbar.columnSetting.visibleColumns[index] = item
                            }
                            this.$set(this.defaultConfig.columns, index, item)
                          })
                        }} >
                          <a-checkbox style="width: 100%;pointer-events: all;" indeterminate={this.toolbar.columnSetting.indeterminate} checked={this.toolbar.columnSetting.checkAll}>{this.__('table.columnSetting')}</a-checkbox>
                        </div>
                      </a-menu-item>
                      {
                        (() => {
                          return this.defaultConfig.columns.map((item, index) => {
                            return (<a-menu-item style="padding: 0;">
                              <div style="padding: 5px 12px;" onClick={(e) => {
                                e.stopPropagation()
                                e.preventDefault()
                                item.visible = item.visible === false
                                this.$set(this.defaultConfig.columns, index, item)
                                if (item.visible !== false) {
                                  this.toolbar.columnSetting.visibleColumns[index] = item
                                } else {
                                  delete this.toolbar.columnSetting.visibleColumns[index]
                                }
                                const visibleColumnsLength = Object.keys(this.toolbar.columnSetting.visibleColumns).length
                                this.toolbar.columnSetting.checkAll = visibleColumnsLength === this.defaultConfig.columns.length
                                this.toolbar.columnSetting.indeterminate = !!visibleColumnsLength && visibleColumnsLength < this.defaultConfig.columns.length
                              }} >
                                <a-checkbox style="width: 100%;pointer-events: all;" checked={item.visible !== false ? 'checked' : false}>{item.title}</a-checkbox>
                              </div>
                            </a-menu-item>)
                          })
                        })()
                      }
                  </a-menu>
                  <a-button icon="setting" style="border:none"></a-button>
                </a-dropdown>
              </a-tooltip>
              <a-tooltip placement="top">
                <template slot="title"><span>{this.__('table.export')}</span></template><a-button icon="export" style="border:none" onClick={(e) => {
                  const t = this
                  const columns = this.defaultConfig.columns
                  const response = this.tableResponse
                  const filename = this.defaultConfig.tableTitle

                  Utils.dialog(t, () => import('@/components/YS/ExportTask/add'), { columns, response, filename }, {
                  title: t.__('Export task'),
                  on: {
                    close (e) {
                      console.log(e)
                    }
                  }
                })
              }}></a-button>
              </a-tooltip>
            </a-button-group>
          </a-row>
        </a-col>
      </a-row>
      )
    },
    // 渲染表格
    renderTable () {
      const h = this.$createElement
      const props = {}
      Object.keys(T.props).forEach(k => {
        this.$data.defaultConfig[k] !== undefined && (props[k] = this.$data.defaultConfig[k])
        if (k === 'columns') {
          // 控制列展示隐藏
          props.columns = props.columns.filter((column) => {
            return column.visible !== false
          })
        }
      })
      return h('a-table', {
        props,
        scopedSlots: { ...this.$scopedSlots },
        on: {
          change: this.loadData,
          expand: (expanded, record) => this.$emit('expand', expanded, record)
        }
      }, this.$slots)
    }
  },
  render (h) {
    console.log('table render')

    const tableChildren = []

    this.defaultConfig.showSearch && tableChildren.push(this.renderTableSearch())
    tableChildren.push(this.renderTableToolbar())
    this.inited && tableChildren.push(this.renderTable())

    return h('div', {
      class: 'table-wrapper',
      ref: 'table-wrapper',
      style: 'background-color: #ffffff;'
    }, tableChildren)
  }
}
